package com.nerve.secondhandcar.service.impl;

import java.util.Date;
import java.util.List;

import org.ko.core.dao.support.Finder;
import org.ko.core.dao.support.Updater;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import com.nerve.secondhandcar.common.C;
import com.nerve.secondhandcar.controller.CarController;
import com.nerve.secondhandcar.controller.model.CarCategoryModel;
import com.nerve.secondhandcar.controller.model.CarModel;
import com.nerve.secondhandcar.dao.BrandDao;
import com.nerve.secondhandcar.dao.CarDao;
import com.nerve.secondhandcar.dao.car.CarCategoryDao;
import com.nerve.secondhandcar.domain.Brand;
import com.nerve.secondhandcar.domain.Car;
import com.nerve.secondhandcar.domain.car.CarCategory;
import com.nerve.secondhandcar.domain.car.Configure;
import com.nerve.secondhandcar.domain.car.ConfigureBottom;
import com.nerve.secondhandcar.domain.car.ConfigureControl;
import com.nerve.secondhandcar.domain.car.ConfigureIn;
import com.nerve.secondhandcar.domain.car.ConfigureMedia;
import com.nerve.secondhandcar.domain.car.ConfigureMotor;
import com.nerve.secondhandcar.domain.car.ConfigureOut;
import com.nerve.secondhandcar.domain.report.Report;
import com.nerve.secondhandcar.domain.report.ReportDrive;
import com.nerve.secondhandcar.domain.report.ReportPaint;
import com.nerve.secondhandcar.domain.report.ReportPerform;
import com.nerve.secondhandcar.domain.report.ReportSecurity;
import com.nerve.secondhandcar.domain.report.ReportTrouble;
import com.nerve.secondhandcar.service.CarService;

/**
 * 平台中的汽车对象Service接口实现
 * @author 集成显卡
 * @version 2014-10-09 10:51:08
 */
@Service
@Transactional
public class CarServiceImpl implements CarService {

	@Autowired
	private CarDao dao;
	@Autowired
	private BrandDao brandDao;
	@Autowired
	private CarCategoryDao categoryDao;

	@Override
	public Car basicDo(CarModel model) throws Exception {
		Car car = model.getCar();
		Assert.notNull(car, "对象不能为空，请填写汽车信息");
		
		Brand brand = car.getBrand();
		Assert.notNull(brand, "请选择品牌");
		
		Brand brand2 = brandDao.get(brand.getId());
		Assert.notNull(brand2, "你选择的品牌不存在，请重新选择");
		car.setBrand(brand2);
		buildFullName(car);
		
		//判断Category
		if(car.getCategory() != null){
			if(!car.getCategory().isUsable())
				car.setCategory(null);
		}
		
		//新车时，需要判断品牌名称
		if(car.getId() == null || car.getId() <= 0){
			Configure confg = new Configure(car);
			car.setConfigure(confg);
			
			Report report = new Report(car);
			car.setReport(report);
			
			car.setPostDate(new Date());
			dao.save(car);
		}else{
			Updater<Car> updater = new Updater<Car>(car);
			dao.updateByUpdater(updater);
		}
		
		return car;
	}
	
	/**
	 * 生成汽车的全名，格式： 2004款 大众高尔夫-1.6自动舒适版
	 * @method name: buildFullName
	 * @return type: void
	 *	@param car
	 */
	private void buildFullName(Car car){
		StringBuilder sb = new StringBuilder(car.getRegYear());
		sb.append("款 ");
		if(car.getBrand().getParent() != null)
			sb.append(car.getBrand().getParent().getName());
		sb.append(car.getBrand().getName());
		sb.append("-");
		sb.append(car.getName());
		
		car.setFullName(sb.toString());
	}
	
	public void create(CarModel model)throws Exception{
		Car entity = model.getCar();
		if(entity != null){
			if(entity.getId() != null && entity.getId() >0){
				dao.merge(entity);
			}else{
				dao.save(entity);
			}
		}
	}
	/**
	 * 删除实体
	 * @param model
	 * @throws Exception
	 */
	public void delete(CarModel model)throws Exception{
//		dao.delete(model.getId());
		
		trashCar(model.getId());
	}
	
	/**
	 * 刷新实体
	 * @param model
	 * @throws Exception
	 */
	public void refresh(CarModel model)throws Exception{
		
	}
	
	/**
	 * 浏览详情
	 * @param model
	 * @throws Exception
	 */
	public void view(CarModel model)throws Exception{
		Car entity = dao.get(model.getId());
		Assert.notNull(entity, "你查看的对象不存在");
		
		//点击+1
		dao.runHql("update Car set clickAmount=clickAmount+1 where id="+model.getId());
		model.setCar(entity);
	}
	
	/**
	 * 分页浏览
	 * @param model
	 * @throws Exception
	 */
	public void list(CarModel model)throws Exception{
		StringBuilder sb = new StringBuilder("FROM Car where 1=1");
		sb.append(" and trash!="+C.DELETE_ENTITY);
		
		if(StringUtils.hasText(model.getKeyword())){
			sb.append(" and fullName like '%"+model.getKeyword()+"%'");
		}
		
		Finder f = Finder.create(sb.toString());
		f.append(" order by id desc");
		
		dao.find(f, model);
	}
	
	/**
	 * 判断实体是否存在
	 * @param model
	 * @return
	 * @throws Exception
	 */
	public boolean isExist(CarModel model)throws Exception{
		return false;
	}

	@Override
	public Car get(long id) throws Exception {
		return dao.get(id);
	}
	
	@Override
	public void add(CarModel model) throws Exception {
		Car car = dao.get(model.getId());
		
		Assert.notNull(car, "找不到汽车对象，请先创建");
		
		if(car.getTrash() == C.DELETE_ENTITY)
			throw new Exception("汽车对象已被删除，在还原之前无法编辑");
		
		if(model.getTemplate().equals(CarController.CONFIGURE)){
			if(car.getConfigure() == null){
				car.setConfigure(new Configure(car));
				dao.merge(car);
			}else{
				Configure cfg = car.getConfigure();
				if(cfg.getBottom() == null)
					cfg.setBottom(new ConfigureBottom());
				if(cfg.getMedia() == null)
					cfg.setMedia(new ConfigureMedia());
				if(cfg.getIn() == null)
					cfg.setIn(new ConfigureIn());
				if(cfg.getOut() == null)
					cfg.setOut(new ConfigureOut());
				if(cfg.getMotor() == null)
					cfg.setMotor(new ConfigureMotor());
				if(cfg.getControl() == null)
					cfg.setControl(new ConfigureControl());
			}
		}
		else if(model.getTemplate().equals(CarController.REPORT)){
			if(car.getReport() == null){
				car.setReport(new Report(car));
				dao.merge(car);
			}else{
				Report report = car.getReport();
				if(report.getDrive()==null)
					report.setDrive(new ReportDrive());
				if(report.getPerform()==null)
					report.setPerform(new ReportPerform());
				if(report.getTrouble()==null)
					report.setTrouble(new ReportTrouble());
				if(report.getSecurity() == null)
					report.setSecurity(new ReportSecurity());
				if(report.getPaint()==null)
					report.setPaint(new ReportPaint());
			}
		}
		//加载Category
		else if(model.getTemplate().equals(CarController.BASIC)){
			model.setCategoryList(categoryList());
		}
		
		model.setCar(car);
	}
	
	@Override
	public List categoryList() {
		Finder f = Finder.create("FROM CarCategory order by sort desc");
		return categoryDao.find(f);
	}

	@Override
	public void configureDo(CarModel model) throws Exception {
		Car car = model.getCar();
		Assert.notNull(car, "对象不能为空，请填写汽车信息");
		
		Updater<Car> updater = new Updater<Car>(car);
		updater.exclude("price").exclude("freshPrice");
		dao.updateByUpdater(updater);
	}
	
	/**
	 * on 2014-10-25
	 * 实际测试中，执行更新操作的时候，会出现汽车的价格变为0的情况
	 * 所以增加了：
	 * updater.exclude("price").exclude("freshPrice");
	 * 
	 */
	@Override
	public void reportDo(CarModel model) throws Exception {
		Car car = model.getCar();
		Assert.notNull(car, "对象不能为空，请填写汽车信息");
		
		Report re = car.getReport();
		Assert.notNull(re, "测评对象不能为空");
		Assert.hasText(re.getLevel(), "骨架得分必须填写");
		
		figureGrade(re);
		
		if(re.getEvaluators() != null){
			if(!re.getEvaluators().isUsable())
				re.setEvaluators(null);
		}
		
		Updater<Car> updater = new Updater<Car>(car);
		updater.exclude("price").exclude("freshPrice");
		dao.updateByUpdater(updater);
	}
	
	/**
	 * 计算最终得分
	 * <pre>
	 * 测评书里面的：
		等级 = 骨架部件得分
		得分 = 外观部件 + 内饰部件 + 性能部件
		
		评定规则:
		评定	等级	得分		结果
		6	A	60 +	极优+
		5	A	不足 60	极优
		4	B	60 +	优秀+
		3	B	不足60	优秀
		2	C	60+		良好
		1	C	不足60	一般
		0	其他			较差
	 * </pre>
	 * @method name: figureGrade
	 * @return type: void
	 *	@param re
	 */
	private void figureGrade(Report re){
		int score = re.getScoreIn()+re.getScoreOut()+re.getScorePerform();
		re.setScore(score);
		
		int grade = 6;
		if(LEVEL_A.equalsIgnoreCase(re.getLevel())){
			grade -= score > GRAGE_LIMIT?0:1;
		}
		else if(LEVEL_B.equalsIgnoreCase(re.getLevel())){
			grade -= score > GRAGE_LIMIT?2:3;
		}
		else if(LEVEL_C.equalsIgnoreCase(re.getLevel())){
			grade -= score > GRAGE_LIMIT?4:5;
		}
		else {
			grade = 0;
		}
		
		re.setGrade(grade);
	}

	@Override
	public void delete(Long[] ids) throws Exception {
		for(long l:ids){
			trashCar(l);
		}
	}
	
	@Override
	public int specialPrice(CarModel model) {
		Car car = dao.get(model.getId());
		Assert.notNull(car, "汽车对象为空");
		
		car.setSpecialPrice(car.getSpecialPrice()==0?1:0);
		dao.merge(car);
		return car.getSpecialPrice();
	}
	
	@Override
	public int changeStatus(CarModel model) {
		Car car = dao.get(model.getId());
		Assert.notNull(car, "汽车对象为空");
		
		car.setStatus(car.getStatus()==Car.PENDING?Car.SALED:Car.PENDING);
		dao.merge(car);
		return car.getStatus();
	}
	
	private void trashCar(long id){
		dao.runSql("update "+dao.getTableName()+" set trash="+C.DELETE_ENTITY+" where id="+id);
	}

	/**
	 * 优先处理Ids
	 */
	@Override
	public void categoryDelete(CarCategoryModel model) throws Exception {
		if(model.getIds() != null && model.getIds().length > 0){
			for(Long l:model.getIds())
				categoryDeleteDo(l.longValue());
		}else if(model.getId() > 0){
			categoryDeleteDo(model.getId());
		}
	}
	
	private void categoryDeleteDo(long id){
		//先删除Car对category的引用
		dao.runHql("update Car set category=null where category.id="+id);
		categoryDao.delete(id);
	}

	@Override
	public void categoryList(CarCategoryModel model) throws Exception {
		Finder f = Finder.create("FROM CarCategory order by sort desc");
		
		categoryDao.find(f, model);
	}

	@Override
	public void categorySave(CarCategoryModel model) throws Exception {
		CarCategory category = model.getCategory();
		Assert.notNull(category, "类型对象不能为空");
		
		if(category.getId() != null && category.getId() >0 ){
			categoryDao.merge(category);
		}else{
			categoryDao.save(category);
		}
	}
}